<template>
  <div class="v-calendar-warp">
    <div class="v-calendar-content">
      <div class="title">
        <div class="year">
          {{year}}
        </div>
        <div class="month">
          <i
            class="iconfont icon-zuojiantou"
            @click="prevMonth"
            :class="{disabled:prevMonth()}"
          ></i>
          <span>{{month}}月</span>
          <i
            class="iconfont icon-youjiantou"
            @click="nextMonth"
            :class="{disabled:nextMonth()}"
          ></i>
        </div>
      </div>
      <ul class="week">
        <li>Mon</li>
        <li>Tues</li>
        <li>Wed</li>
        <li>Thur</li>
        <li>Fri</li>
        <li>Sat</li>
        <li>Sun</li>
      </ul>
      <div
        class="day-warp"
        ref="dayWarp"
      >
        <ul
          class="day-list"
          :class="{crowd:dayList.length > 35}"
        >
          <li
            v-for="(item,index) in dayList"
            class="current"
            :class="{prev: currentMonth.firstWeek - 1 > index,next:dayList.length - 1 - (7 - currentMonth.lastWeek) < index, active:item.active}"
            :key="index"
            @mouseenter="mouseenter(item,$event)"
            @mouseleave="mouseleave(item,$event)"
          >{{item.day}}</li>
        </ul>
        <div
          class="tip-warp"
          ref="tip"
          :style="tipStyle"
          :class="{right:tip.position === 'right'}"
        >
          <span :class="tip.position === 'right'?'right':'left'"></span>
          <div class="tip">
            <div class="pic">
              <img
                :src="tip.activeInfo.ewm"
                alt=""
              >
            </div>
            <div class="texts">
              <div class="periods">
                {{tip.activeInfo.title}}
              </div>
              <div class="content">
                单词训练营开班啦!
              </div>
              <p>扫码报名参加～</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import tool from "@/tool/tool";
export default {
  props: ["start", "end", "classInfo"],
  data() {
    return {
      // 天数列表
      dayList: [],
      // 当前月
      currentMonth: {
        // 总天数
        length: 0,
        // 第一天是周几
        firstWeek: 0,
        // 最后一天是周几
        lastWeek: 0,
        // date对象
        time: 0
      },
      // 当前激活的月份
      month: 0,
      // 当前激活的年份
      year: 0,
      // tip激活的信息
      tip: {
        activeInfo: {},
        width: 0,
        position: "left"
      }
    };
  },
  computed: {
    // 开始时间
    startTime() {
      let date = new Date(this.start);
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let day = date.getDate();
      return {
        year,
        month,
        day,
        date
      };
    },
    // 结束时间
    endTime() {
      let date = new Date(this.end);
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      let day = date.getDate();
      return {
        year,
        month,
        day,
        date
      };
    },
    // tip的样式
    tipStyle() {
      let obj = Object.assign(
        {},
        {
          width: this.tip.width + "px",
          top: this.tip.top + "px"
        }
      );
      if (this.tip.right) {
        obj = Object.assign(obj, {
          right: this.tip.right + "px"
        });
      }
      if (this.tip.left) {
        obj = Object.assign(obj, {
          left: this.tip.left + "px"
        });
      }
      return obj;
    }
  },
  methods: {
    // 获取日期列表
    getDayList(date) {
      let time = new Date(date);
      // 复制当前月份
      this.month = this.getCurrentMonth(time).month;
      this.year = this.getCurrentMonth(time).year;

      // 获取本月天数
      let currentDayLength = this.getCurrentDayLength(time);
      // 获取本月第一天是星期几
      let currentWeekFirst = this.getCurrentFirstWeek(time);
      // 获取本月最后一天是星期几
      let currentWeekLast = this.getCurrentLastWeek(time);
      // 获取上月最后一天是几号
      let prevLastDay = this.getPrevLastDay(time);
      // 复制全局
      this.currentMonth.length = currentDayLength;
      this.currentMonth.firstWeek = currentWeekFirst;
      this.currentMonth.lastWeek = currentWeekLast;
      this.currentMonth.time = time;

      // 筛选需要激活的数据
      let filter = this.filtrateActiveData(time);

      // 渲染数据
      let array = [];
      for (let i = 0; i < currentDayLength; i++) {
        let date = {};
        date.day = i + 1;
        for (let f = 0, len = filter.length; f < len; f++) {
          if (i + 1 == filter[f].day) {
            date.active = true;
            date.filter = filter[f];
          }
        }
        array.push(date);
      }
      for (let i = 1, len = currentWeekFirst; i < len; i++) {
        array.unshift({
          day: prevLastDay
        });
        prevLastDay--;
      }
      for (let i = 0, len = 7 - currentWeekLast; i < len; i++) {
        array.push({
          day: i + 1
        });
      }
      this.dayList = array;
    },
    //当前月的天数
    getCurrentDayLength(date) {
      let getyear = date.getFullYear();
      let getmonth = date.getMonth() + 1;
      let currentMonthLasttDay = new Date(getyear, getmonth, 0);
      return currentMonthLasttDay.getDate();
    },
    // 获取当月第一天的星期
    getCurrentFirstWeek(date) {
      let getyear = date.getFullYear();
      let getmonth = date.getMonth();
      let currentMonthFirstWeek = new Date(getyear, getmonth, 1);
      return currentMonthFirstWeek.getDay() || 7;
    },
    // 获取当月最后一天的星期
    getCurrentLastWeek(date) {
      let getyear = date.getFullYear();
      let getmonth = date.getMonth() + 1;
      let currentMonthFirstWeek = new Date(getyear, getmonth, 0);
      return currentMonthFirstWeek.getDay() || 7;
    },
    // 获取上月最后一天
    getPrevLastDay(date) {
      let getyear = date.getFullYear();
      let getmonth = date.getMonth();
      let currentMonthFirstWeek = new Date(getyear, getmonth, 0);
      return currentMonthFirstWeek.getDate();
    },
    // 获取下个月的信息
    getNextMonth(date) {
      let getyear = date.getFullYear();
      let getmonth = date.getMonth() + 1;
      let next = new Date(getyear, getmonth);
      return {
        month: next.getMonth() + 1,
        year: next.getFullYear(),
        date: next
      };
    },
    // 获取当前月年月
    getCurrentMonth(date) {
      let year = date.getFullYear();
      let month = date.getMonth() + 1;
      return {
        year,
        month
      };
    },
    // 获取上个月的信息
    getPrevMonth(date) {
      let getyear = date.getFullYear();
      let getmonth = date.getMonth() - 1;
      let getday = this.getPrevLastDay(date);
      let next = new Date(getyear, getmonth, getday);
      return {
        month: next.getMonth() + 1,
        year: next.getFullYear(),
        date: next
      };
    },
    // 筛选需要激活的日历为本月的数据
    filtrateActiveData(date) {
      let current = this.getCurrentMonth(date);
      let year = current.year;
      let month = current.month;
      let data = [];
      let filter = tool.deepClone(this.classInfo);
      filter.forEach(item => {
        let a_date = new Date(item.time);
        let a_year = a_date.getFullYear();
        let a_month = a_date.getMonth() + 1;
        let a_day = a_date.getDate();
        if (year === a_year && a_month === month) {
          item.day = a_day;
        }
      });
      return filter;
    },
    // 上个月
    prevMonth(event) {
      let prev = this.getPrevMonth(this.currentMonth.time).date;
      let start = this.startTime.date;
      if (prev < start) return true;
      if (event) {
        this.getDayList(prev);
      }
    },
    // 下个月
    nextMonth(event) {
      let next = this.getNextMonth(this.currentMonth.time).date;
      let end = this.endTime.date;
      if (next > end) return true;
      if (event) {
        this.getDayList(next);
      }
    },
    // 鼠标滑过
    mouseenter(item, event) {
      if (!item.active) return;
      clearTimeout(this.timer);
      let _this = event.target;
      this.tip.activeInfo = item.filter;
      this.tip.width = 363;

      let top =
        _this.offsetTop -
        this.$refs.tip.offsetHeight / 2 +
        _this.offsetHeight / 2;
      let left = _this.offsetLeft + _this.offsetWidth + 20;
      let right = this.$refs.dayWarp.offsetWidth - _this.offsetLeft + 20;
      this.tip.top = top;
      if (left + 363 > this.$refs.dayWarp.offsetWidth + 363 / 2) {
        this.tip.position = "right";
        this.tip.right = right;
        return;
      }
      this.tip.left = left;
    },
    // 鼠标滑出
    mouseleave(item, event) {
      if (!item.active) return;
      this.tip.width = 0;
      this.timer = setTimeout(() => {
        this.tip.activeInfo = {};
        this.tip.position = "left";
        this.tip.left = 0;
        this.tip.right = 0;
      }, 300);
    }
  },
  created() {
    this.getDayList(this.endTime.date);
  }
};
</script>

<style lang="less" scoped>
@import "~assets/css/function.less";
.v-calendar-warp {
  padding: 30px 53px;
  background-color: #f5f9ff;
}

.title {
  line-height: 51px;
  height: 51px;
}

.year {
  float: left;
  .font(30px, #333333);
}

.month {
  float: right;
  .font(22px, #333333);
  margin-bottom: 10px;
  i {
    cursor: pointer;
    padding: 5px;
    .font(14px, #808080);
    &.disabled {
      color: #cecdcd;
      cursor: not-allowed;
    }
  }
  span {
    margin: 0 55px;
    display: inline-block;
    width: 60px;
    text-align: center;
  }
}

.week {
  width: 100%;
  .flex();
  border-bottom: 1px solid #acb3c3;
  li {
    width: 40px;
    padding-left: 5px;
    .font(16px, #acb3c3);
    line-height: 60px;
  }
}

.day-warp {
  position: relative;
}

.day-list {
  .flex();
  flex-wrap: wrap;
  justify-content: flex-start;
  li {
    width: 40px;
    margin-right: 45px;
    height: 40px;
    text-align: center;
    line-height: 40px;
    font-size: 22px;
    margin-top: 27px;
    cursor: pointer;
    border-radius: 50%;
    &:nth-of-type(7n) {
      margin-right: 0;
    }
    &.current {
      color: #4c4c4c;
    }
    &.prev {
      color: #d8dce6;
    }
    &.next {
      color: #d8dce6;
    }
    &.active {
      color: #fff;
      background-color: #ff7d95;
    }
  }
  &.crowd {
    li {
      margin-top: 20px;
    }
  }
}

.tip-warp {
  position: absolute;
  width: 0;
  overflow: hidden;
  height: 184px;
  transition: width 0.5s;
  border-radius: 10px;
  box-shadow: 4px 4px 10px rgba(56, 85, 215, 0.1);
  span {
    background-color: #fff;
    height: 14px;
    width: 14px;
    transform: rotate(45deg);
    position: absolute;
    top: 50%;
    margin-top: -7px;
    &.right {
      right: 0;
    }
    &.left {
      left: 0;
    }
  }
  &.right {
    box-shadow: -4px -4px 10px rgba(56, 85, 215, 0.1);
    .tip {
      left: 0;
    }
  }
}

.tip {
  position: absolute;
  left: 7px;
  border-radius: 10px;
  padding: 10px;
  box-sizing: border-box;
  background-color: #fff;
  .flex();
  .pic {
    width: 163px;
    height: 163px;
    img {
      width: 100%;
      height: 100%;
    }
  }
  .texts {
    width: 173px;
  }
  .periods {
    margin-top: 17px;
    line-height: 40px;
    .font(30px, #333333);
  }
  .content {
    line-height: 34px;
    .font(20px, #333333);
  }
  p {
    margin-top: 25px;
    font-size: 16px;
    color: #4c4c4c;
    font-weight: 600;
  }
}
</style>
